﻿using FrameWork.Plugin;
using MyServer.Common;
using ScreenMonitor.ClientLib.Plugin;
using ScreenMonitor.Common;
using ScreenMonitor.Common.File;
using ScreenMonitor.Common.Hooks;
using ScreenMonitor.Common.Objects;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace ScreenMonitor.ClientLib
{
    public static class TcpCommandOperator
    {
        private static object commandRunLock = new object();
        public static bool RunCommand(DataPackageCollection col)
        {
            lock (commandRunLock)
            {
                try
                {
                    string command = Util.GetCommandLine(col.PackageName);
                    switch (command)
                    {
                        case CommandType.GetName:
                            ServerObject.SetClientName(ClientGlobalSetting.ClientName);
                            break;
                        case CommandType.Start:
                            ClientTask.IsPauseSendBitmap = !ClientTask.IsAutoStartSendImg;
                            ClientTask.SendBitMapTask.Start();
                            break;
                        case CommandType.Ping:
                            ServerObject.Reping();
                            break;
                        case CommandType.PauseSendBitMap:
                            ClientTask.IsPauseSendBitmap = true;
                            break;
                        case CommandType.StartSendBitMap:
                            ClientTask.IsPauseSendBitmap = false;
                            break;
                        case CommandType.SetBitMapSendRate:
                            ClientTask.SendBitmapRate = BitConverter.ToInt32(DataPacker.UnPackData(col), 0);
                            break;
                        case CommandType.SendBitMap:
                            ClientTask.DoSendBitmap();
                            break;
                        case CommandType.SetBitMapSize:
                            ClientTask.BitmapSize = Util.ByteToSize(DataPacker.UnPackData(col));
                            break;
                        case CommandType.SetBitMapFormat:
                            ClientTask.BitMapFormat = Encoding.UTF8.GetString((DataPacker.UnPackData(col)));
                            break;
                        case CommandType.SendMessage:
                            DoSendMessage(col);
                            break;
                        case CommandType.NeedToSign:
                            SignRequestObject obj = SignRequestObject.FromByte(DataPacker.UnPackData(col));
                            ServerObject.OnNeedToSign(null, new OperateObjectEventArgs(obj));
                            break;
                        case CommandType.StartControl:
                            ClientTask.IsPauseSendBitmap = true;
                            break;
                        case CommandType.DoMouseEvent:
                            MouseEventObject meve = MouseEventObject.FromByte(DataPacker.UnPackData(col));
                            ClientObjects.MouseHooker.MouseWork(meve);
                            ClientTask.DoSendBitmap();
                            break;
                        case CommandType.DoKeyBoardEvent:
                            KeyBoardEventObject keve = KeyBoardEventObject.FromByte(DataPacker.UnPackData(col));
                            switch (keve.Type)
                            {
                                case KeyBoardType.Key_Down:
                                    KeyBoardHook.KeyDown(keve.KeyCode);
                                    break;
                                case KeyBoardType.Key_Press:
                                    KeyBoardHook.KeyDown(keve.KeyCode);
                                    KeyBoardHook.KeyUp(keve.KeyCode);
                                    break;
                                case KeyBoardType.Key_Up:
                                    KeyBoardHook.KeyUp(keve.KeyCode);
                                    break;
                            }
                            ClientTask.DoSendBitmap();
                            break;
                        case CommandType.StopControl:
                            ClientTask.IsPauseSendBitmap = false;
                            break;
                        case CommandType.SendFile:
                            DoSendFile(col);
                            break;
                        case CommandType.WantToSendFile:
                            DoWantToSendFile(col);
                            break;
                        case CommandType.SetBitMapSizeMode:
                            ClientTask.SendBitmapSizeMode = (PictureBoxSizeMode)BitConverter.ToInt32(DataPacker.UnPackData(col), 0);
                            break;
                        default:
                            RunPluginCommand(command, col);
                            break;
                    }
                    return true;
                }
                catch
                {
#if DEBUG
                throw;
#else
                    return false;
#endif
                }
            }
        }



        private static object lock1 = new object();
        private static bool DoWantToSendFile(DataPackageCollection Col)
        {
            lock (lock1)
            {
                FileRequestObject obj = FileRequestObject.FromByte(DataPacker.UnPackData(Col), Col.Tag);
                obj.FileOffset = 0;
                obj.ReauestType = FileRequestType.Open;
                if (ServerObject.ClientBase == obj.Tag)
                {
                    ServerObject.OnWantToSendFile(null, new OperateObjectEventArgs(obj));
                }
                return true;
            }
        }

        private static object lock2 = new object();
        private static bool DoSendMessage(DataPackageCollection Col)
        {
            lock (lock2)
            {
                SendMessageObject obj = SendMessageObject.FromByte(DataPacker.UnPackData(Col));
                ServerObject.OnSendMessage(null, new OperateObjectEventArgs(obj));
                return true;
            }
        }

        private static object lock3 = new object();
        private static bool DoSendFile(DataPackageCollection Col)
        {
            lock (lock3)
            {
                FileRequestObject Obj = FileRequestObject.FromByte(DataPacker.UnPackData(Col), Col.Tag);
                FileRequestObject ReObj;
                FilePool.DoRequestObject(Obj, out ReObj);
                if (ReObj != null)
                {
                    ServerObject.SendFile(ReObj);
                }
                return true;
            }
        }

        private static object lock4 = new object();
        private static bool RunPluginCommand(string command, DataPackageCollection col)
        {
            lock (lock4)
            {
                foreach (IClientPlugin plu in PluginPool.GetPlugins())
                {
                    bool IsMatched = false;
                    foreach (string com in plu.GetCommands())
                    {
                        if (com == command)
                        {
                            plu.RunCommand(command, DataPacker.UnPackData(col));
                            IsMatched = true;
                            break;
                        }
                    }
                    if (IsMatched)
                        break;
                }
                return true;
            }
        }
    }
}
